<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  
  <title>ryansecreat blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
<meta property="og:type" content="website">
<meta property="og:title" content="ryansecreat blog">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="ryansecreat blog">
<meta property="og:description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="ryansecreat blog">
<meta name="twitter:description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
  
    <link rel="alternate" href="/atom.xml" title="ryansecreat blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  

  
  <link rel="stylesheet" href="/css/style.css">
  

</head>
</html>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">ryansecreat blog</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">smile hard</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-security-1" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/12/09/security-1/" class="article-date">
  <time datetime="2019-12-09T10:11:18.000Z" itemprop="datePublished">2019-12-09</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/12/09/security-1/">security</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="xss"><a href="#xss" class="headerlink" title="xss"></a>xss</h3><p>XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码，当用户浏览该页之时，嵌入其中 Web 里面的脚本代码会被执行，从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。</p>
<ol>
<li>反射型 XSS </li>
</ol>
<p>一般是通过给别人发送带有恶意脚本代码参数的 URL，当 URL 地址被打开时，特有的恶意代码参数被 HTML 解析、执行。<br>不过一些浏览器如Chrome其内置了一些XSS过滤器，可以防止大部分反射型XSS攻击。</p>
<p>反射型 XSS 漏洞常见于通过 URL 传递参数的功能，如网站搜索、跳转等</p>
<p>非持久型 XSS 漏洞攻击有以下几点特征：</p>
<p>即时性，不经过服务器存储，直接通过 HTTP 的 GET 和 POST 请求就能完成一次攻击，拿到用户隐私数据。<br>攻击者需要诱骗点击,必须要通过用户点击链接才能发起<br>反馈率低，所以较难发现和响应修复<br>盗取用户敏感保密信息</p>
<ol start="2">
<li>存储型 XSS</li>
</ol>
<p>持久型 XSS 漏洞，一般存在于 Form 表单提交等交互功能，如文章留言，提交文本信息等，黑客利用的 XSS 漏洞，将内容经正常功能提交进入数据库持久保存，当前端页面获得后端从数据库中读出的注入代码时，恰好将其渲染执行。</p>
<p>这种攻击常见于带有用户保存数据的网站功能，如论坛发帖、商品评论、用户私信等。</p>
<p>持久型 XSS 有以下几个特点：</p>
<p>持久性，植入在数据库中<br>盗取用户敏感私密信息<br>危害面广</p>
<p>3.DOM xss</p>
<p>它不需要服务器解析响应的直接参与，触发XSS靠的是浏览器端的DOM解析，可以认为完全是客户端的事情。  解决方案通过csp: sript-src 的nonce值处理。</p>
<p>4.jsonp 服务端做处理</p>
<p>防御措施：1. httponly 2. csp 3.转义字符—现在的后端模板引擎都实现了转义 </p>
<p>增加攻击难度，降低攻击后果</p>
<p><a href="https://xss-game.appspot.com/level1" target="_blank" rel="noopener">https://xss-game.appspot.com/level1</a></p>
<p>如果用 Vue/React 技术栈，并且不使用 v-html/dangerouslySetInnerHTML 功能，就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患。</p>
<h3 id="csrf"><a href="#csrf" class="headerlink" title="csrf"></a>csrf</h3><p>CSRF（Cross-site request forgery）跨站请求伪造：攻击者诱导受害者进入第三方网站，在第三方网站中，向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证，绕过后台的用户验证，达到冒充用户对被攻击的网站执行某项操作的目的。</p>
<p>CSRF的特点<br>攻击一般发起在第三方网站，而不是被攻击的网站。被攻击的网站无法防止攻击发生。<br>攻击利用受害者在被攻击网站的登录凭证，冒充受害者提交操作；而不是直接窃取数据。<br>整个过程攻击者并不能获取到受害者的登录凭证，仅仅是“冒用”。<br>跨站请求可以用各种方式：图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中，难以进行追踪。</p>
<p>针对已上特点：同源检测 </p>
<ol>
<li>同源检测 </li>
</ol>
<p>在HTTP协议中，每一个异步请求都会携带两个Header，用于标记来源域名：</p>
<ul>
<li>Origin Header</li>
<li>Referer Header<br>这两个Header在浏览器发起请求时，大多数情况会自动带上，并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名，确定请求的来源域</li>
</ul>
<p>但是Origin在以下两种情况下并不存在：</p>
<ul>
<li>IE11同源策略： IE 11 不会在跨站CORS请求上添加Origin标头，Referer头将仍然是唯一的标识。最根本原因是因为IE 11对同源的定义和其他浏览器有不同，有两个主要的区别，可以参考MDN Same-origin_policy#IE_Exceptions</li>
</ul>
<ul>
<li>302重定向： 在302重定向之后Origin不包含在重定向的请求中，因为Origin可能会被认为是其他来源的敏感信息。对于302重定向的情况来说都是定向到新的服务器上的URL，因此浏览器不想将Origin泄漏到新的服务器上。</li>
</ul>
<h4 id="使用Referer-Header确定来源域名"><a href="#使用Referer-Header确定来源域名" class="headerlink" title="使用Referer Header确定来源域名"></a>使用Referer Header确定来源域名</h4><p>根据HTTP协议，在HTTP头中有一个字段叫Referer，记录了该HTTP请求的来源地址。 对于Ajax请求，图片和script等资源请求，Referer为发起请求的页面地址。对于页面跳转，Referer为打开页面历史记录的前一个页面地址。因此我们使用Referer中链接的Origin部分可以得知请求的来源域名。</p>
<p>通过refer 检测，可以定义不同的refer policy<br>攻击者可以在自己的请求中隐藏Referer。<br>CSRF大多数情况下来自第三方域名，但并不能排除本域发起。如果攻击者有权限在本域发布评论（含链接、图片等，统称UGC），那么它可以直接在本域发起攻击，这种情况下同源策略无法达到防护的作用。</p>
<p>综上所述：同源验证是一个相对简单的防范方法，能够防范绝大多数的CSRF攻击。但这并不是万无一失的，对于安全性要求较高，或者有较多用户输入内容的网站，我们就要对关键的接口做额外的防护措施。</p>
<h4 id="CSRF-Token"><a href="#CSRF-Token" class="headerlink" title="CSRF Token"></a>CSRF Token</h4><p>CSRF攻击之所以能够成功，是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token，来把正常的请求和攻击的请求区分开，也可以防范CSRF的攻击。</p>
<p>Token是一个比较有效的CSRF防护方法，只要页面没有XSS漏洞泄露Token，那么接口的CSRF攻击就无法成功。</p>
<p>验证码和密码其实也可以起到CSRF Token的作用哦，而且更安全。</p>
<h4 id="双重Cookie验证"><a href="#双重Cookie验证" class="headerlink" title="双重Cookie验证"></a>双重Cookie验证</h4><p>利用CSRF攻击不能获取到用户Cookie的特点，我们可以要求Ajax和表单请求携带一个Cookie中的值。</p>
<p>此方法相对于CSRF Token就简单了许多。可以直接通过前后端拦截的的方法自动化实现。后端校验也更加方便，只需进行请求中字段的对比，而不需要再进行查询和存储Token。</p>
<p>当然，此方法并没有大规模应用，其在大型网站上的安全性还是没有CSRF Token高，原因我们举例进行说明。</p>
<ol>
<li>用双重Cookie防御CSRF的优点：</li>
</ol>
<p>无需使用Session，适用面更广，易于实施。<br>Token储存于客户端中，不会给服务器带来压力。<br>相对于Token，实施成本更低，可以在前后端统一拦截校验，而不需要一个个接口和页面添加。</p>
<ol start="2">
<li>缺点：</li>
</ol>
<p>无法使用httponly，这样造成了cookie的安全风险。<br>难以做到子域名的隔离。<br>为了确保Cookie传输安全，采用这种防御方式的最好确保用整站HTTPS的方式，如果还没切HTTPS的使用这种方式也会有风险。</p>
<p>Samesite Cookie属性</p>
<p>####Samesite Cookie属性</p>
<p>防止CSRF攻击的办法已经有上面的预防措施。为了从源头上解决这个问题，Google起草了一份草案来改进HTTP协议，那就是为Set-Cookie响应头新增Samesite属性，它用来标明这个 Cookie是个“同站 Cookie”，同站Cookie只能作为第一方Cookie，不能作为第三方Cookie，Samesite 有两个属性值，分别是 Strict 和 Lax，下面分别讲解：</p>
<p>Samesite=Strict<br>这种称为严格模式，表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie，绝无例外。比如说 b.com 设置了如下 Cookie：</p>
<p>Samesite=Lax 打开链接或者页面跳转时可带Cookie</p>
<ol>
<li>另外一个问题是Samesite的兼容性不是很好，现阶段除了从新版Chrome和Firefox支持以外，Safari以及iOS Safari都还不支持，现阶段看来暂时还不能普及。</li>
<li>SamesiteCookie目前有一个致命的缺陷：不支持子域。例如，种在topic.a.com下的Cookie，并不能使用a.com下种植的SamesiteCookie。这就导致了当我们网站有多个子域名时，不能使用SamesiteCookie在主域名存储用户登录信息。每个子域名都需要用户重新登录一次。</li>
</ol>
<ol>
<li>点击劫持</li>
<li>url 跳转漏洞(url 钓鱼)</li>
<li>图片钓鱼</li>
<li>iframe 钓鱼</li>
<li>os 命令注入</li>
</ol>
<p>strict-transport-security HTTP Strict Transport Security（通常简称为HSTS）是一个安全功能，它告诉浏览器只能通过HTTPS访问当前资源，而不是HTTP</p>
<ol>
<li>post 请求，用户访问该网页后激发 2. 链接类 用户点击后激发</li>
</ol>
<p>利用的form 表单、URL 跳转</p>
<p>waf:</p>
<ol>
<li>Web攻击防护：帮助您防护SQL注入、XSS跨站攻击等常见的Web攻击。</li>
<li>CC攻击防护：帮助您防护针对页面请求的CC攻击。</li>
<li>恶意IP惩罚：帮助您自动封禁在短时间内进行多次Web攻击的客户端IP。</li>
<li>地理IP封禁：帮助您一键封禁来自指定国内省份或海外地区的IP的访问请求。</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/12/09/security-1/" data-id="ck3ya0yif000q0d8szp4hpret" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/web-安全/">web 安全</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-encoding" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/11/08/encoding/" class="article-date">
  <time datetime="2019-11-08T06:11:43.000Z" itemprop="datePublished">2019-11-08</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/11/08/encoding/">encoding</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>charCodeAt() 返回表示给定索引的字符的Unicode的值。 codePointAt() 返回使用UTF-16编码的给定位置的值的非负整数。</li>
<li>Transfer-Encoding   数据以一系列分块的形式进行发送。 Content-Length 首部在这种情况下不被发送。。在每一个分块的开头需要添加当前分块的长度，以十六进制的形式表示，后面紧跟着 ‘\r\n’ ，之后是分块本身，后面也是’\r\n’ 。终止块是一个常规的分块，不同之处在于其长度为0。终止块后面是一个挂载（trailer），由一系列（或者为空）的实体消息首部构成。</li>
<li>ascii 第一个bit为0，也就是当第一个bit是0时仍表示之前那些常用的字符.当为1时就表示其他补充的字符，例如西欧国家的文字。</li>
<li><p>utf-8  Refer:<a href="https://segmentfault.com/a/1190000014324711" target="_blank" rel="noopener">https://segmentfault.com/a/1190000014324711</a></p>
<pre><code class="text">0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit.就表示把一个字节做为一个单元.就跟ASCII完全一样.
110xxxxx 10xxxxxx.如果是这样的格式,则把两个字节当一个单元

1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元
</code></pre>
</li>
<li></li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/11/08/encoding/" data-id="ck3ya0yhf00010d8senl31fn9" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-graphql" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/08/23/graphql/" class="article-date">
  <time datetime="2019-08-23T08:19:28.000Z" itemprop="datePublished">2019-08-23</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/08/23/graphql/">graphql</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function(parent, args, ctx, info) &#123;</span><br><span class="line">    …</span><br><span class="line">其中的参数的意义如下：</span><br><span class="line"></span><br><span class="line">parent: 当前上一个Resolver的返回值</span><br><span class="line">args: 传入某个Query中的函数（比如上面例子中article(id: Int)中的id）</span><br><span class="line">ctx: 在Resolver解析链中不断传递的中间变量（类似中间件架构中的context）</span><br><span class="line">info: 当前Query的AST对象</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>query（查询）：当获取数据时，应当选取Query类型</p>
<p>mutation（更改）：当尝试修改数据时，应当使用mutation类型</p>
<p>subscription（订阅）：当希望数据更改时，可以进行消息推送，使用subscription类型</p>
</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/08/23/graphql/" data-id="ck3ya0yiu00160d8sk6ka2l1n" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-linux" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/07/02/linux/" class="article-date">
  <time datetime="2019-07-02T03:39:34.000Z" itemprop="datePublished">2019-07-02</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/07/02/linux/">linux</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="vim"><a href="#vim" class="headerlink" title="vim"></a>vim</h3>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/07/02/linux/" data-id="ck3ya0yij000t0d8sck380061" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ops/">ops</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-es8" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/07/02/es8/" class="article-date">
  <time datetime="2019-07-02T03:37:11.000Z" itemprop="datePublished">2019-07-02</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/07/02/es8/">es8</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li><p>Stage 0: strawman——最初想法的提交。<br>Stage 1: proposal（提案）——由TC39至少一名成员倡导的正式提案文件，该文件包括API事例。<br>Stage 2: draft（草案）——功能规范的初始版本，该版本包含功能规范的两个实验实现。<br>Stage 3: candidate（候选）——提案规范通过审查并从厂商那里收集反馈<br>Stage 4: finished（完成）——提案准备加入ECMAScript，但是到浏览器或者Nodejs中可能需要更长的时间</p>
</li>
<li><p>es2018(es9)<br>promise.finally  正则表达式匹配组<br>regex 先行断言和反向断言、dotall  </p>
</li>
<li><p>Template Literals</p>
</li>
<li></li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/07/02/es8/" data-id="ck3ya0yhv00090d8sy4jom2ma" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/es/">es</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-es6" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/06/28/es6/" class="article-date">
  <time datetime="2019-06-28T03:58:20.000Z" itemprop="datePublished">2019-06-28</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/06/28/es6/">es6</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="reflect"><a href="#reflect" class="headerlink" title="reflect"></a>reflect</h3><ol>
<li><p>修改某些Object方法的返回结果，让其变得更合理</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 老写法</span></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">  <span class="built_in">Object</span>.defineProperty(target, property, attributes);</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 新写法</span></span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">Reflect</span>.defineProperty(target, property, attributes)) &#123;</span><br><span class="line">  <span class="comment">// success</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="comment">// failure</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>命令式改为函数式</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 老写法</span></span><br><span class="line"><span class="string">'assign'</span> <span class="keyword">in</span> <span class="built_in">Object</span> <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 新写法</span></span><br><span class="line"><span class="built_in">Reflect</span>.has(<span class="built_in">Object</span>, <span class="string">'assign'</span>) <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>Reflect对象的方法与Proxy对象的方法一一对应</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Proxy</span>(target, &#123;</span><br><span class="line">  <span class="keyword">set</span>: function(target, name, value, receiver) &#123;</span><br><span class="line">    <span class="keyword">var</span> success = <span class="built_in">Reflect</span>.set(target, name, value, receiver);</span><br><span class="line">    <span class="keyword">if</span> (success) &#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'property '</span> + name + <span class="string">' on '</span> + target + <span class="string">' set to '</span> + value);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> success;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>####async 函数是什么？一句话，它就是 Generator 函数的语法糖。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> readFile = <span class="function"><span class="keyword">function</span> (<span class="params">fileName</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve, reject</span>) </span>&#123;</span><br><span class="line">    fs.readFile(fileName, <span class="function"><span class="keyword">function</span>(<span class="params">error, data</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (error) <span class="keyword">return</span> reject(error);</span><br><span class="line">      resolve(data);</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> gen = <span class="function"><span class="keyword">function</span>* (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> f1 = <span class="keyword">yield</span> readFile(<span class="string">'/etc/fstab'</span>);</span><br><span class="line">  <span class="keyword">const</span> f2 = <span class="keyword">yield</span> readFile(<span class="string">'/etc/shells'</span>);</span><br><span class="line">  <span class="built_in">console</span>.log(f1.toString());</span><br><span class="line">  <span class="built_in">console</span>.log(f2.toString());</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<h3 id="module"><a href="#module" class="headerlink" title="module"></a>module</h3><ol>
<li>CommonJS 模块输出的是值的拷贝，也就是说，一旦输出一个值，模块内部的变化就影响不到这个值。<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> counter = <span class="number">3</span>;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">incCounter</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  counter++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  counter: counter,</span><br><span class="line">  incCounter: incCounter,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.js</span></span><br><span class="line"><span class="keyword">var</span> mod = <span class="built_in">require</span>(<span class="string">'./lib'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(mod.counter);  <span class="comment">// 3</span></span><br><span class="line">mod.incCounter();</span><br><span class="line"><span class="built_in">console</span>.log(mod.counter); <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>可以使用Es6 加载commonjs 模块。 CommonJS 模块的输出缓存机制，在 ES6 加载方式下依然有效。</p>
<p>CommonJS 模块加载 ES6 模块，不能使用require命令，而要使用import()函数。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// es.mjs</span></span><br><span class="line"><span class="keyword">let</span> foo = &#123; <span class="attr">bar</span>: <span class="string">'my-default'</span> &#125;;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> foo;</span><br><span class="line"></span><br><span class="line"><span class="comment">// cjs.js</span></span><br><span class="line"><span class="keyword">const</span> es_namespace = <span class="keyword">await</span> <span class="keyword">import</span>(<span class="string">'./es.mjs'</span>);</span><br><span class="line"><span class="comment">// es_namespace = &#123;</span></span><br><span class="line"><span class="comment">//   get default() &#123;</span></span><br><span class="line"><span class="comment">//     ...</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(es_namespace.default);</span><br><span class="line"><span class="comment">// &#123; bar:'my-default' &#125;</span></span><br></pre></td></tr></table></figure>
<h3 id="lit"><a href="#lit" class="headerlink" title="lit"></a>lit</h3><ol>
<li><p>数组的空位 [,,,]</p>
</li>
<li><p>parentheses to be omitted, as in</p>
</li>
</ol>
<p>try {<br>  // …<br>} catch {<br>  // …<br>}</p>
<h3 id="generator"><a href="#generator" class="headerlink" title="generator"></a>generator</h3><ol>
<li><p>Generator  yield表达式后面的表达式，只有当调用next方法、内部指针指向该语句时才会执行，因此等于为 JavaScript 提供了手动的“惰性求值”（Lazy Evaluation）的语法功能。<br>yield表达式本身没有返回值，或者说总是返回undefined。next方法可以带一个参数，该参数就会被当作上一个yield表达式的返回值。</p>
</li>
<li><p>Co 模块相关于一个generator 的执行器。co 模块其实就是将两种自动执行器（Thunk 函数和 Promise 对象），包装成一个模块。使用 co 的前提条件是，Generator 函数的yield命令后面，只能是 Thunk 函数或 Promise 对象。</p>
</li>
<li><p>代码中，虽然map方法的参数是async函数，但它是并发执行的，因为只有async函数内部是继发执行，外部不受影响。后面的for..of循环内部使用了await，因此实现了按顺序输出</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">logInOrder</span>(<span class="params">urls</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 并发读取远程URL</span></span><br><span class="line">  <span class="keyword">const</span> textPromises = urls.map(<span class="keyword">async</span> url =&gt; &#123;</span><br><span class="line">    <span class="keyword">const</span> response = <span class="keyword">await</span> fetch(url);</span><br><span class="line">    <span class="keyword">return</span> response.text();</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 按次序输出</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">const</span> textPromise <span class="keyword">of</span> textPromises) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="keyword">await</span> textPromise);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>对象的Symbol.iterator</p>
<p>由于 Generator 函数就是遍历器生成函数，因此可以把 Generator 赋值给对象的Symbol.iterator属性，从而使得该对象具有 Iterator 接口。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myIterable = &#123;&#125;;</span><br><span class="line">myIterable[<span class="built_in">Symbol</span>.iterator] = <span class="function"><span class="keyword">function</span>* (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">1</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">2</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="number">3</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">[...myIterable]</span><br></pre></td></tr></table></figure>
<p>Iterator 接口和generator 函数：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  * [<span class="built_in">Symbol</span>.iterator]() &#123;</span><br><span class="line">    <span class="keyword">yield</span> <span class="string">'hello'</span>;</span><br><span class="line">    <span class="keyword">yield</span> <span class="string">'world'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
</li>
<li><p>只要 Generator 函数内部部署了try…catch代码块，那么遍历器的throw方法抛出的错误，不影响下一次遍历。</p>
<p>Gnerator 嵌套：</p>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">inner</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">       <span class="keyword">yield</span> <span class="string">'hello!'</span>;</span><br><span class="line">   &#125;</span><br><span class="line">   </span><br><span class="line">   <span class="function"><span class="keyword">function</span>* <span class="title">outer1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">       <span class="keyword">yield</span> <span class="string">'open'</span>;</span><br><span class="line">       <span class="keyword">yield</span> *inner();</span><br><span class="line">       <span class="keyword">yield</span> <span class="string">'close'</span>;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
<ol>
<li>异步的同步表达：</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">main</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> result = <span class="keyword">yield</span> request(<span class="string">"http://some.url"</span>);</span><br><span class="line">  <span class="keyword">var</span> resp = <span class="built_in">JSON</span>.parse(result);</span><br><span class="line">    <span class="built_in">console</span>.log(resp.value);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">request</span>(<span class="params">url</span>) </span>&#123;</span><br><span class="line">  makeAjaxCall(url, <span class="function"><span class="keyword">function</span>(<span class="params">response</span>)</span>&#123;</span><br><span class="line">    it.next(response);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> it = main();</span><br><span class="line">it.next();</span><br></pre></td></tr></table></figure>
<h3 id="proxy"><a href="#proxy" class="headerlink" title="proxy"></a>proxy</h3><ol>
<li><p>Proxy 的 construct 用于拦截 new()<br>isExtensible方法拦截Object.isExtensible操作。<br>ownKeys方法用来拦截对象自身属性的读取操作。具体来说，拦截以下操作。</p>
<p>Object.getOwnPropertyNames()<br>Object.getOwnPropertySymbols()<br>Object.keys()<br>for…in循环</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = <span class="keyword">new</span> <span class="built_in">Proxy</span>(&#123;&#125;, &#123;</span><br><span class="line">     <span class="keyword">get</span>: function (target, key, receiver) &#123;</span><br><span class="line">       <span class="built_in">console</span>.log(<span class="string">`getting <span class="subst">$&#123;key&#125;</span>!`</span>);</span><br><span class="line">       <span class="keyword">return</span> <span class="built_in">Reflect</span>.get(target, key, receiver);</span><br><span class="line">     &#125;,</span><br><span class="line">     <span class="keyword">set</span>: function (target, key, value, receiver) &#123;</span><br><span class="line">       <span class="built_in">console</span>.log(<span class="string">`setting <span class="subst">$&#123;key&#125;</span>!`</span>);</span><br><span class="line">       <span class="keyword">return</span> <span class="built_in">Reflect</span>.set(target, key, value, receiver);</span><br><span class="line">     &#125;</span><br><span class="line">   &#125;);</span><br></pre></td></tr></table></figure>
</li>
<li><p>Class 的generator :</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line">     <span class="keyword">constructor</span>(...args) &#123;</span><br><span class="line">       <span class="keyword">this</span>.args = args;</span><br><span class="line">     &#125;</span><br><span class="line">     * [<span class="built_in">Symbol</span>.iterator]() &#123;</span><br><span class="line">       <span class="keyword">for</span> (<span class="keyword">let</span> arg <span class="keyword">of</span> <span class="keyword">this</span>.args) &#123;</span><br><span class="line">         <span class="keyword">yield</span> arg;</span><br><span class="line">       &#125;</span><br><span class="line">     &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>绑定上下文</p>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">selfish</span> (<span class="params">target</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> cache = <span class="keyword">new</span> <span class="built_in">WeakMap</span>();</span><br><span class="line">  <span class="keyword">const</span> handler = &#123;</span><br><span class="line">    <span class="keyword">get</span> (target, key) &#123;</span><br><span class="line">      <span class="keyword">const</span> value = <span class="built_in">Reflect</span>.get(target, key);</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> value !== <span class="string">'function'</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> value;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">if</span> (!cache.has(value)) &#123;</span><br><span class="line">        cache.set(value, value.bind(target));</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> cache.get(value);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">const</span> proxy = <span class="keyword">new</span> <span class="built_in">Proxy</span>(target, handler);</span><br><span class="line">  <span class="keyword">return</span> proxy;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> logger = selfish(<span class="keyword">new</span> Logger());</span><br><span class="line"><span class="string">``</span><span class="string">`   </span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">#### 类型转换 </span></span><br><span class="line"><span class="string">1. 转换为数字</span></span><br><span class="line"><span class="string">`</span><span class="string">``</span>javascript</span><br><span class="line"><span class="keyword">let</span> int = <span class="string">"15"</span>;</span><br><span class="line">int = +int;</span><br><span class="line"><span class="built_in">console</span>.log(int); <span class="comment">// Result: 15</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> int); Result: <span class="string">"number"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//这也可以用于将布尔值转换为数字，如下所示</span></span><br><span class="line"> <span class="built_in">console</span>.log(+<span class="literal">true</span>);  <span class="comment">// Return: 1</span></span><br><span class="line"> <span class="built_in">console</span>.log(+<span class="literal">false</span>); <span class="comment">// Return: 0</span></span><br></pre></td></tr></table></figure>
<h4 id="console"><a href="#console" class="headerlink" title="console"></a>console</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="built_in">console</span>.table()</span><br><span class="line"><span class="built_in">console</span>.dir()</span><br><span class="line"><span class="built_in">console</span>.count()</span><br><span class="line">Console.time() </span><br><span class="line">consoel.timeLog()</span><br><span class="line"> <span class="built_in">console</span>.time(<span class="string">"answer time"</span>);</span><br><span class="line">alert(<span class="string">"Click to continue"</span>);</span><br><span class="line"><span class="built_in">console</span>.timeEnd(<span class="string">"answer time”);</span></span><br></pre></td></tr></table></figure>
<h4 id="对象的结构"><a href="#对象的结构" class="headerlink" title="对象的结构"></a>对象的结构</h4><ol>
<li><p>对象的解构：let { x, y, …z } = { x: 1, y: 2, a: 3, b: 4 };</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;   <span class="attr">p</span>: [     <span class="string">'Hello'</span>,     &#123; <span class="attr">y</span>: <span class="string">'World'</span> &#125;   ] &#125;; </span><br><span class="line"><span class="keyword">let</span> &#123; <span class="attr">p</span>: [x, &#123; y &#125;] &#125; = obj; x <span class="comment">// "Hello"</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>展开运算符的妙用 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//需要根据一个条件创建两个不同的对象，可以使用展开运算符号来处理。</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> getUser = <span class="function">(<span class="params">emailIncluded</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    name: <span class="string">'John'</span>,</span><br><span class="line">    surname: <span class="string">'Doe'</span>,</span><br><span class="line">    ...emailIncluded &amp;&amp; &#123; <span class="attr">email</span> : <span class="string">'john@doe.com'</span> &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>####</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/06/28/es6/" data-id="ck3ya0yhz000c0d8skm9c53gh" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/es/">es</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-cookies" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/06/24/cookies/" class="article-date">
  <time datetime="2019-06-24T06:40:18.000Z" itemprop="datePublished">2019-06-24</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/06/24/cookies/">cookies</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>:smile:</p>
<h3 id="发版"><a href="#发版" class="headerlink" title="发版"></a>发版</h3><ol>
<li>发布阶段：更新chagelog ,打 git tag 。</li>
</ol>
<h3 id="word"><a href="#word" class="headerlink" title="word"></a>word</h3><ol>
<li>deflate 放气，紧缩</li>
<li>Sanitize 消毒，净化</li>
<li><h3 id="js"><a href="#js" class="headerlink" title="js"></a>js</h3></li>
<li><p>随机字符串 Math.random().toString(36).substr(2));</p>
</li>
<li><p>Babel pollyfy 的作用 ：<a href="https://zhuanlan.zhihu.com/p/29058936" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/29058936</a></p>
</li>
<li><p>Babel stag2 的功能  <a href="https://github.com/babel/babel/tree/master/packages/babel-preset-stage-2" target="_blank" rel="noopener">https://github.com/babel/babel/tree/master/packages/babel-preset-stage-2</a></p>
</li>
<li>所有的babel 包  <a href="https://github.com/babel/babel/tree/master/packages" target="_blank" rel="noopener">https://github.com/babel/babel/tree/master/packages</a></li>
<li>npx babel-upgrade</li>
<li>ES2019 中为Symbol对象添加了只读属性 description ，该对象返回包含Symbol描述的字符串。</li>
<li>变量的临时死区  </li>
<li>SET 操作的时间复杂度</li>
<li>如果你传的 context 就 null 或者 undefined，那么 window 对象就是默认的 context（严格模式下默认 context 是 undefined）</li>
<li>高阶函数的定义</li>
<li>作用域以及作用域链  函数作用域 —闭包</li>
<li>ES6 模块功能是它的导入模块是导出时模块的实时只读视图。（相比起 CommonJS，导入的是导出模块的拷贝副本，因此也不是实时的）。只读视图和内存拷贝的区别。</li>
<li>atob() 对经过 base-64 编码的字符串进行解码,btoa() base64加吗</li>
<li>Console.dir  显示对象所有的属性和方法</li>
<li>Broadcast Channel API 允许同一原始域和用户代理下的所有窗口,iFrames 等进行交互。也就是说，如果用户打开了同一个网站的的两个标签窗口，如果网站内容发生了变化，那么两个窗口会同时得到更新通知。</li>
<li>escape 在处理 0xff 之外字符的时候，是直接使用字符的 unicode 在前面加上一个 「%u」，而encodeURI则是先进行 UTF-8，再在 UTF-8 的每个字节码前加上一个 「%」； 所以通过encodeUrI 可以获取utf-8 字节长度</li>
<li>js value</li>
<li>Prototype 包含constructor 和 <strong>proto</strong>. 原型链存储共有的属性和方法，减少内存</li>
<li><p>基本的数据类型 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">基本的数据类型</span><br><span class="line">undefined</span><br><span class="line">null</span><br><span class="line">string</span><br><span class="line">boolean</span><br><span class="line">number</span><br><span class="line">symbol(ES6)</span><br></pre></td></tr></table></figure>
</li>
<li><p>navigator.userAgent: 返回当前浏览器的user agent字符串</p>
</li>
<li>懒加载：<br>Javascript 脚步通常要等到 DOM 加载完后才会执行，如果加载的资源过多，可能会影响网页的正常使用。<br>能够节省流量和减轻服务器压力，更近一步就是能够为公司省成本。</li>
<li>String 和 new String 区别</li>
<li></li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">对象转原始类型，会调用内置的[ToPrimitive]函数，对于该函数而言，其逻辑如下：</span><br><span class="line"></span><br><span class="line">如果Symbol.toPrimitive()方法，优先调用再返回</span><br><span class="line">调用valueOf()，如果转换为原始类型，则返回</span><br><span class="line">调用toString()，如果转换为原始类型，则返回</span><br><span class="line">如果都没有返回原始类型，会报错</span><br><span class="line">var a = &#123;</span><br><span class="line">  value: 0,</span><br><span class="line">  valueOf: function() &#123;</span><br><span class="line">    this.value++;</span><br><span class="line">    return this.value;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">console.log(a == 1 &amp;&amp; a == 2);//true</span><br></pre></td></tr></table></figure>
<ol>
<li>Same origin 可以使用broadcast channel 两页面间通信。</li>
<li>注意闭包内this的指向</li>
<li></li>
</ol>
<h4 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h4><ol>
<li>无论你使用的是解释型语言(JavaScript、Python、Ruby)还是编译型语言(c#、Java、Rust)，都有一个共同的部分:将源代码作为纯文本解析为 抽象语法树(abstract syntax tree, AST) 的数据结构。</li>
<li>AST 不仅以结构化的方式显示源代码，而且在语义分析中扮演着重要角色。在语义分析中，编译器验证程序和语言元素的语法使用是否正确。之后，使用 AST 来生成实际的字节码或者机器码。</li>
<li><p>转义的过程：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">编写ES6代码</span><br><span class="line">babylon 进行解析</span><br><span class="line">解析得到 AST</span><br><span class="line">plugin 用 babel-traverse 对 AST 树进行遍历转译</span><br><span class="line">得到新的 AST树</span><br><span class="line">用 babel-generator 通过 AST 树生成 ES5 代码</span><br></pre></td></tr></table></figure>
</li>
<li><p>要应用更新，Virtual DOM核心功能将发挥作用，即 协调算法，它的工作是提供最优的解决方案来解决以前和当前虚拟DOM 状态之间的差异。</p>
</li>
</ol>
<h2 id="opentracing"><a href="#opentracing" class="headerlink" title="opentracing"></a>opentracing</h2><ol>
<li>Opentracing 的carrier 有多种实现，tracer 的inject（客户端进程） 和 extract（服务端进程），这样 客户端和服务端 就可以拥有相同的trace context。</li>
<li>Server 首先extract check 有没有注入的span，没有的话启动一个新的span</li>
</ol>
<h2 id="mac"><a href="#mac" class="headerlink" title="mac"></a>mac</h2><ol>
<li>Mac 设置path  export PATH=$PATH:</li>
<li>查看端口占用：lsof -i:3001</li>
<li>export http_proxy=”<a href="http://localhost:8899&quot;" target="_blank" rel="noopener">http://localhost:8899&quot;</a></li>
<li>Grep -A 5 显示后面5行信息</li>
</ol>
<h2 id="npm"><a href="#npm" class="headerlink" title="npm"></a>npm</h2><ol>
<li>npm config edit</li>
<li>npm config set init.author.name “ryansecreat”</li>
<li>npm config set <a href="mailto:init.email=&#39;chenjingnan@jd.com" target="_blank" rel="noopener">init.email=&#39;chenjingnan@jd.com</a>’</li>
<li>npm config set init.license “MIT”</li>
<li>npm start –prefix path/to/your/folder   //指定目录下运行</li>
<li>npm repo   浏览器中打开repo</li>
<li>npm publish –registry=<a href="http://registry.npmjs.org" target="_blank" rel="noopener">http://registry.npmjs.org</a>  –registry=<a href="https://registry.npm.taobao.org" target="_blank" rel="noopener">https://registry.npm.taobao.org</a></li>
<li>npm outdated  查看过时package</li>
<li>npm publish –tag=beta.</li>
<li>npm version patch -m “Upgrade to %s for reasons”</li>
<li>npm dist-tag add <a href="mailto:n-n-n-n@1.0.2-1" target="_blank" rel="noopener">n-n-n-n@1.0.2-1</a> latest  将某个预发版本更新为最新   </li>
<li>npm ping [–registry <registry>]</registry></li>
</ol>
<h3 id="node"><a href="#node" class="headerlink" title="node"></a>node</h3><ol>
<li>Stream cork uncork</li>
<li>escape-html  This function will escape the following characters: “, ‘, &amp;, &lt;, and &gt;.</li>
<li>domain模块，把处理多个不同的IO的操作作为一个组。注册事件和回调到domain，当发生一个错误事件或抛出一个错误时，domain对象会被通知，不会丢失上下文环境，也不导致程序错误立即退出，与process.on(‘uncaughtException’)不同。</li>
<li><p>stream tranform</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">const &#123; Transform &#125; = require(&apos;stream&apos;);</span><br><span class="line"></span><br><span class="line">const myTransform = new Transform(&#123;</span><br><span class="line">  transform(chunk, encoding, callback) &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以引入corejs实现feature</p>
</li>
<li><p>性能分析<br>Node 性能分析，抓取火焰图 node –inspect app.js<br>Node  –prof-process  <a href="https://github.com/nswbmw/node-in-debugging/blob/master/1.3%20Tick%20Processor.md" target="_blank" rel="noopener">https://github.com/nswbmw/node-in-debugging/blob/master/1.3%20Tick%20Processor.md</a></p>
</li>
<li><p>一个promise类 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Sleep</span> </span>&#123;</span><br><span class="line">then(resolve, reject)&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>Node 内置了pipeline  const { pipeline } = require(‘stream’);</p>
</li>
<li>Elastic APM 是 Elastic 公司开源的一款 APM 工具</li>
<li>Error.prepareStackTrace:定制化堆栈信息    Error.captureStackTrace:隐藏内部的实现细节，优化错误栈。</li>
<li>const { EventEmitter } = require(‘events’);  EventEmitter 的继承</li>
<li>Require.resovle() 获取模块的绝对路径  </li>
<li>peerDependencies 相关模块安装</li>
<li>websocket </li>
<li>cors 新浏览器<br>SameSite=Strict: The cookie is only sent if you are currently on the site that the cookie is set for. If you are on a different site and you click a link to a site that the cookie is set for, the cookie is not sent with the first request.</li>
<li></li>
<li></li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">WebSocket 使用了自定义的二进制分帧格式，把每个应用消息切分成一或多个帧，发送到目的地之后再组装起来，等到接收到完整的消息后再通知接收端。基本的成帧协议定义了帧类型有操作码、有效载荷的长度，指定位置的Extension data和Application data，统称为Payload data，保留了一些特殊位和操作码供后期扩展。在打开握手完成后，终端发送一个关闭帧之前的任何时间里，数据帧可能由客户端或服务器的任何一方发送。</span><br><span class="line"></span><br><span class="line">• 帧：最小的通信单位，包含可变长度的帧首部和净荷部分，净荷可能包含完整或部分应用消息。</span><br><span class="line">• 消息：一系列帧，与应用消息对等。</span><br></pre></td></tr></table></figure>
<ol>
<li>jwt 签名算法<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">HS256 使用密钥生成固定的签名，RS256 使用成非对称进行签名。简单地说，HS256 必须与任何想要验证 JWT的 客户端或 API 共享秘密。</span><br><span class="line">RS256 生成非对称签名，这意味着必须使用私钥来签签名 JWT，并且必须使用对应的公钥来验证签名。与对称算法不同，使用 RS256 可以保证服务端是 JWT 的签名者，因为服务端是唯一拥有私钥的一方。这样做将不再需要在许多应用程序之间共享私钥</span><br><span class="line"></span><br><span class="line">这种方法可以让我们分离开签发与验证，签发时需要用一个密钥，验证时使用公钥，也就是有公钥的地方只能做验证，但不能签发 JWT。</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="egg"><a href="#egg" class="headerlink" title="egg"></a>egg</h3><ol>
<li>启动顺序<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Master 启动后先 fork Agent 进程</span><br><span class="line">Agent 初始化成功后，通过 IPC 通道通知 Master</span><br><span class="line">Master 再 fork 多个 App Worker</span><br><span class="line">App Worker 初始化成功，通知 Master</span><br><span class="line">所有的进程初始化成功后，Master 通知 Agent 和 Worker 应用启动成功</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h3><ol>
<li><p>子网是所属VPC IP地址范围内的 IP 地址块。目前私有网络中的云资源部署在子网内，如云主机、容器、负载均衡等。子网：子网是对VPC地址空间的再一次划分，用户可以在子网中创建云主机。</p>
</li>
<li><p>可用区（Availability Zone）是电力及网络之间互相独立的物理区域，相同可用区内的实例之间较之同地域不同可用区内实例之间的网络延时更小。同地域内不同可用区之间提供内网互通环境，可用区之间可做到故障隔离。<br>若您的业务要求有较低网络时延，建议将实例或者Pod部署在同一可用区内。</p>
</li>
<li>VPC：VPC是用户网络在京东云上的表现形式，包含了一系列的网络功能，与其他的VPC逻辑隔离。VPC有一个网络地址空间，用户可以在其中继续划分子网。</li>
<li><p>NAT 地址网络转换，通过在路由器上安装 NAT 软件，它至少有一个有效的公网 IP 地址，通过 NAT 路由器将内部私有 IP 转换成公网 IP。它的问题在于 NAT 设备自动屏蔽了非内网主机主动发起的连接，也就是说，从外网发往内网的数据包将被 NAT 设备丢弃，这使得位于不同 NAT 设备之后的主机之间无法直接交换信息.</p>
</li>
<li><p>503 服务器资源不足问题导致的拒绝服务，比如熔断。</p>
</li>
<li><p>Options  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1. 检测服务支持的method</span><br><span class="line">2. Cors 预检</span><br></pre></td></tr></table></figure>
</li>
<li><p>HTTP HEAD 方法 请求资源的头部信息, 并且这些头部与 HTTP GET 方法请求时返回的一致. 该请求方法的一个使用场景是在下载一个大文件前先获取其大小再决定是否要下载, 以此可以节约带宽资源.</p>
</li>
<li>WebSocket是基于Http协议的，或者说借用了Http协议来完成一部分握手，在握手阶段与Http是相同的。我们来看一个websocket握手协议的实现，基本是2个属性，upgrade，connection。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Upgrade:webSocket</span><br><span class="line">Connection:Upgrade</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="html"><a href="#html" class="headerlink" title="html"></a>html</h3><ol>
<li>Web quality  : alt</li>
<li><p>该WindowEventHandlers.onstorage属性包含一个在storage事件触发时运行的事件处理程序。当更改存储区域时会发生这种情况（例如，存储新项目）。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">window</span>.onstorage = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123; <span class="built_in">console</span>.log(<span class="string">'The '</span> + e.key + <span class="string">' key has been changed from '</span> + e.oldValue + <span class="string">' to '</span> + e.newValue + <span class="string">'.'</span>); &#125;;</span><br></pre></td></tr></table></figure>
</li>
<li><p>navigator.sendBeacon() 方法可用于通过HTTP将少量数据异步传输到Web服务器。</p>
</li>
</ol>
<h3 id="vim"><a href="#vim" class="headerlink" title="vim"></a>vim</h3><p>j: 下移一行；</p>
<p>k: 上移一行；</p>
<p>w: 前移一个单词，光标停在下一个单词开头；</p>
<p>e: 前移一个单词，光标停在下一个单词末尾；</p>
<p>0: 移动到行首。</p>
<p>$: 移动到行尾。</p>
<p>n|: 把光标移到递n列上</p>
<p>zz: 将当前行移动到屏幕中央。</p>
<p>o: 在下面新建一行插入；</p>
<p>O: 在上面新建一行插入；</p>
<p>a: 在光标后插入；</p>
<p>A: 在当前行最后插入；</p>
<p>u: 取消一(n)个改动。</p>
<p>ctrl + r: 重做最后的改动。</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/06/24/cookies/" data-id="ck3ya0yhk00030d8s6dj4mb2r" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/零碎/">零碎</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-regex" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/06/24/regex/" class="article-date">
  <time datetime="2019-06-24T05:56:32.000Z" itemprop="datePublished">2019-06-24</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/06/24/regex/">regex</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="s修饰符使得-能够匹配任何字符"><a href="#s修饰符使得-能够匹配任何字符" class="headerlink" title="s修饰符使得 . 能够匹配任何字符"></a>s修饰符使得 . 能够匹配任何字符</h3><p>/foo.bar/s.test(‘foo\nbar’)</p>
<h3 id="非贪婪模式"><a href="#非贪婪模式" class="headerlink" title="? 非贪婪模式"></a>? 非贪婪模式</h3><p>? 非贪婪模式，只匹配最少的数据。 对 “123abc” 应用 /\d+/ 将会返回 “123”，如果使用 /\d+?/,那么就只会匹配到 “1”。</p>
<h3 id="先行断言"><a href="#先行断言" class="headerlink" title="先行断言"></a>先行断言</h3><p>x(?=y)  匹配’x’仅仅当’x’后面跟着’y’.这种叫做先行断言。例如，/Jack(?=Sprat)/会匹配到’Jack’仅仅当它后面跟着’Sprat’。/Jack(?=Sprat|Frost)/匹配‘Jack’仅仅当它后面跟着’Sprat’或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。</p>
<h3 id="后行断言"><a href="#后行断言" class="headerlink" title="后行断言"></a>后行断言</h3><p>(?&lt;=y)x  匹配’x’仅仅当’x’前面是’y’.这种叫做后行断言。</p>
<h3 id="正向否定查找"><a href="#正向否定查找" class="headerlink" title="正向否定查找"></a>正向否定查找</h3><p>x(?!y)   匹配’x’仅仅当’x’后面不跟着’y’,这个叫做正向否定查找。/\d+(?!.)/匹配一个数字仅仅当这个数字后面没有跟小数点的时候。正则表达式/\d+(?!.)/.exec(“3.141”)匹配‘141’而不是‘3.141’</p>
<h3 id="边界"><a href="#边界" class="headerlink" title="边界"></a>边界</h3><p>\b 匹配一个词的边界。<br>\B 匹配一个非单词边界</p>
<h3 id="w"><a href="#w" class="headerlink" title="w"></a>w</h3><p>\w 匹配一个单字字符（字母、数字或者下划线）。<br>等价于[A-Za-z0-9_]。</p>
<p>例如, /\w/ 匹配 “apple,” 中的 ‘a’，”$5.28,”中的 ‘5’ 和 “3D.” 中的 ‘3’。</p>
<p>\W 匹配一个非单字字符。</p>
<p>等价于[^A-Za-z0-9_]。</p>
<p>例如, /\W/ 或者 /[^A-Za-z0-9_]/ 匹配 “50%.” 中的 ‘%’。</p>
<h3 id="子字符串匹配"><a href="#子字符串匹配" class="headerlink" title="子字符串匹配"></a>子字符串匹配</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">var re = /(\w+)\s(\w+)/;</span><br><span class="line">var str = &quot;John Smith&quot;;</span><br><span class="line">var newstr = str.replace(re, &quot;$2, $1&quot;);</span><br><span class="line">console.log(newstr);</span><br></pre></td></tr></table></figure>
<h4 id="非捕获组"><a href="#非捕获组" class="headerlink" title="非捕获组"></a>非捕获组</h4><p>?: 用非捕获组 提升匹配效率。</p>
<p>y修饰符的一个应用，是从字符串提取 token（词元），y修饰符确保了匹配之间不会有漏掉的字符。可以修改regex的 lastIndex 。</p>
<h3 id="具名匹配"><a href="#具名匹配" class="headerlink" title="具名匹配"></a>具名匹配</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">const RE_DATE = /(\d&#123;4&#125;)-(\d&#123;2&#125;)-(\d&#123;2&#125;)/;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">const matchObj = RE_DATE.exec(&apos;1999-12-31&apos;);</span><br><span class="line"></span><br><span class="line">const year = matchObj[1]; // 1999</span><br><span class="line"></span><br><span class="line">const month = matchObj[2]; // 12</span><br><span class="line"></span><br><span class="line">const day = matchObj[3]; // 31</span><br><span class="line"></span><br><span class="line">Replace 函数形式：</span><br><span class="line"></span><br><span class="line">&apos;2015-01-02&apos;.replace(re, (</span><br><span class="line"></span><br><span class="line">   matched, // 整个匹配结果 2015-01-02</span><br><span class="line"></span><br><span class="line">   capture1, // 第一个组匹配 2015</span><br><span class="line"></span><br><span class="line">   capture2, // 第二个组匹配 01</span><br><span class="line"></span><br><span class="line">   capture3, // 第三个组匹配 02</span><br><span class="line"></span><br><span class="line">   position, // 匹配开始的位置 0</span><br><span class="line"></span><br><span class="line">   S, // 原字符串 2015-01-02</span><br><span class="line"></span><br><span class="line">   groups // 具名组构成的一个对象 &#123;year, month, day&#125;</span><br><span class="line"></span><br><span class="line"> ) =&gt; &#123;</span><br><span class="line"></span><br><span class="line"> let &#123;day, month, year&#125; = groups;</span><br><span class="line"></span><br><span class="line"> return `$&#123;day&#125;/$&#123;month&#125;/$&#123;year&#125;`;</span><br><span class="line"></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 可以直接赋值</span></span><br><span class="line"><span class="keyword">let</span> &#123;<span class="attr">groups</span>: &#123;one, two&#125;&#125; = <span class="regexp">/^(?&lt;one&gt;.*):(?&lt;two&gt;.*)$/u</span>.exec(<span class="string">'foo:bar'</span>);</span><br><span class="line">one  <span class="comment">// foo</span></span><br><span class="line">two  <span class="comment">// bar</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 直接replace</span></span><br><span class="line"><span class="keyword">let</span> re = <span class="regexp">/(?&lt;year&gt;\d&#123;4&#125;)-(?&lt;month&gt;\d&#123;2&#125;)-(?&lt;day&gt;\d&#123;2&#125;)/u</span>;</span><br><span class="line"></span><br><span class="line"><span class="string">'2015-01-02'</span>.replace(re, <span class="string">'$&lt;day&gt;/$&lt;month&gt;/$&lt;year&gt;'</span>)</span><br></pre></td></tr></table></figure>
<h3 id="使用引用-具名"><a href="#使用引用-具名" class="headerlink" title="使用引用(具名)"></a>使用引用(具名)</h3><p>使用引用：const RE_TWICE = /^(?<word>[a-z]+)!\k<word>$/;</word></word></p>
<p>RE_TWICE.test(‘abc!abc’) // true<br>RE_TWICE.test(‘abc!ab’) // false</p>
<h3 id="捕获组的使用"><a href="#捕获组的使用" class="headerlink" title="捕获组的使用"></a>捕获组的使用</h3><p>Regex 中捕获组的使用：<br>对于普通捕获组和命名捕获组的引用，语法如下：<br>普通捕获组反向引用：\k<number>，通常简写为\number</number></p>
<p>命名捕获组反向引用：\k<name>或者\k’name’</name></p>
<h3 id="匹配字符和非字符"><a href="#匹配字符和非字符" class="headerlink" title="匹配字符和非字符"></a>匹配字符和非字符</h3><p>\b matches the empty string at the beginning or end of a word. </p>
<p>\B matches the empty string not at the beginning or end of a word. </p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/06/24/regex/" data-id="ck3ya0yip00100d8sisze6v2l" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/regex/">regex</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-http" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/05/14/http/" class="article-date">
  <time datetime="2019-05-14T07:17:39.000Z" itemprop="datePublished">2019-05-14</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/05/14/http/">http</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>####XST 的全称是 Cross-Site Tracing</p>
<pre><code>客户端发 TRACE 请求至服务器，如果服务器按照标准实现了 TRACE 响应，则在 response body 里会返回此次请求的完整头信息。通过这种方式，客户端可以获取某些敏感的头字段，例如 httpOnly 的 Cookie。

TRACE方法让客户端测试到服务器的网络通路，回路的意思如发送一个请返回一个响应，这就是一个请求响应回路
</code></pre><p>####Set-Cookie<br>    用于设置Cookie。</p>
<pre><code>Set-Cookie: name=value; secure; HttpOnly
secure 只在进行HTTP通信时发送Cookie。
HttpOnly 指定不能从JavaScript脚本代码访问Cookie值。
</code></pre><p> ####X-Download-Options: noopen<br>    noopen 用于指定IE 8以上版本的用户不打开文件而直接保存文件。在下载对话框中不显示“打开”选项。</p>
<p> ####keepalive </p>
<pre><code>若connection 模式为close，则服务器主动关闭TCP连接，客户端被动关闭连接，释放TCP连接;若connection 模式为keepalive，则该连接会保持一段时间，在该时间内可以继续接收请求;   
http 1.0中默认是关闭的，需要在http头加入&quot;Connection: Keep-Alive&quot;，才能启用Keep-Alive；http 1.1中默认启用Keep-Alive，如果加入&quot;Connection: close &quot;，才关闭。目前大部分浏览器都是用http1.1协议，也就是说默认都会发起Keep-Alive的连接请求了，所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。
</code></pre><p> ####headers</p>
<p> Accept-Charset： 浏览器申明自己接收的字符集<br> Accept-Encoding： 浏览器申明自己接收的编码方法，通常指定压缩方法，是否支持压缩，支持什么压缩方法（gzip，deflate） </p>
<p>  Age：当代理服务器用自己缓存的实体去响应请求时，用该头部表明该实体从产生到现在经过多长时间了。   </p>
<p>   http header 中使用location 进行302跳转 </p>
<p>   URL.createObjectURL() 静态方法会创建一个 DOMString，其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。</p>
<p>####http<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">http 1.1 添加cache-contol </span><br><span class="line"></span><br><span class="line">长连接：HTTP1.0需要使用keep-alive参数来告知服务器建立一个长连接，而HTP1.1默认支持长连接</span><br><span class="line">节约宽带：HTTP1.1支持只发送一个header信息（不带任何body信息）</span><br><span class="line">host域（设置虚拟站点，也就是说，web server上的多个虚拟站点可以共享同一个ip端口）：HTTP1.0没有host域</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">http 2.0</span><br><span class="line">采用二进制格式传输;</span><br><span class="line">多路复用，其实就是将请求数据分成帧乱序发送到 TCP 中。TCP 只能有一个 steam，所以还是会阻塞;</span><br><span class="line">报头压缩;</span><br><span class="line">服务器推送主动向 B 端发送静态资源，避免往返延迟。</span><br><span class="line">1.http2采用的二进制文本传输数据，而非http1文本格式，二进制在协议的解析和扩展更好</span><br><span class="line">2.数据压缩：对信息头采用了HPACK进行压缩传输，节省了信息头带来的网络流量</span><br><span class="line">3.多路复用：一个连接可以并发处理多个请求</span><br><span class="line">4.服务器推送：我们对支持HTTP2.0的web server请求数据的时候，服务器会顺便把一些客户端需要的资源一起推送到客户端，免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源</span><br><span class="line"></span><br><span class="line">http 3.0</span><br><span class="line">采用 QUIC 协议,自定义连接机制;自定义重传机制;无阻塞的多路复用</span><br><span class="line"></span><br><span class="line">2.按缓存分：强缓存和协商缓存：</span><br><span class="line">2.1强缓存：利用 cache-control 和 expires 设置，直接返回一个过期时间，所以在缓存期间不请求，If-modify-since；</span><br><span class="line">2.2协商缓存：响应头返回 etag 或 last-modified 的哈希值，第二次请求头 If-none-match 或 IF-modify-since 携带上次哈希值，一致则返回 304。</span><br><span class="line">F5 刷新会忽略强缓存不会忽略协商缓存，ctrl+f5 都失效</span><br><span class="line">```       </span><br><span class="line"></span><br><span class="line">1. Https https://zhuanlan.zhihu.com/p/27395037    https://blog.51cto.com/11883699/2160032</span><br><span class="line">1. Ca 使用证书颁发机构的证书中的公钥去解密被颁发者的指纹算法和指纹，并计算比对指纹，正确才能验证身份</span><br><span class="line"></span><br><span class="line">1. 缓存的分类：</span><br><span class="line">```text</span><br><span class="line">   强缓存：在缓存数据未失效的情况下，不需要再和服务器发生交互.cache-control :no-cache 走协商缓存</span><br><span class="line">   协商缓存：需要与服务端校验是否使用缓存。etag If-None-Match HTTP 请求头内提供 ETag</span><br></pre></td></tr></table></figure></p>
<ol>
<li><p>30X 区分</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">301，Moved Permanently。永久重定向，该操作比较危险，需要谨慎操作：如果设置了301，但是一段时间后又想取消，但是浏览器中已经有了缓存，还是会重定向。</span><br><span class="line">302，Fount。临时重定向，但是会在重定向的时候改变 method: 把 POST 改成 GET，于是有了 307</span><br><span class="line">307，Temporary Redirect。临时重定向，在重定向时不会改变 method</span><br></pre></td></tr></table></figure>
</li>
<li></li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/05/14/http/" data-id="ck3ya0yi9000l0d8se2aejfrs" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/http/">http</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-css" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/05/07/css/" class="article-date">
  <time datetime="2019-05-07T07:12:57.000Z" itemprop="datePublished">2019-05-07</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/05/07/css/">css</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>这是一个叫做@font-face 的CSS @规则 ，它允许网页开发者为其网页指定在线字体。 通过这种作者自备字体的方式，@font-face 可以消除对用户电脑字体的依赖。</li>
<li><p>overflow:<a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow" target="_blank" rel="noopener">https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow</a></p>
</li>
<li><p>Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。</p>
</li>
</ol>
<p>offsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。单位px，只读元素。</p>
<p>  scrollHeight: 因为子元素比父元素高，父元素不想被子元素撑的一样高就显示出了滚动条，在滚动的过程中本元素有部分被隐藏了，scrollHeight代表包括当前不可见部分的元素的高度。而可见部分的高度其实就是clientHeight，也就是scrollHeight&gt;=clientHeight恒成立。在有滚动条时讨论scrollHeight才有意义，在没有滚动条时scrollHeight==clientHeight恒成立。单位px，只读元素。</p>
<p>   <a href="https://imweb.io/topic/57c5409e808fd2fb204eef52" target="_blank" rel="noopener">https://imweb.io/topic/57c5409e808fd2fb204eef52</a></p>
<p>   clientheight offsetheight </p>
<ol>
<li><p>相对位置：<br><a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/position" target="_blank" rel="noopener">https://developer.mozilla.org/zh-CN/docs/Web/CSS/position</a></p>
</li>
<li><p>Image alt 属性是一个必需的属性，它规定在图像无法显示时的替代文本。</p>
</li>
</ol>
<p>text-decoration 设置下划线等<br><a href="https://jsfiddle.net/ryansecreat/58um7k43/" target="_blank" rel="noopener">https://jsfiddle.net/ryansecreat/58um7k43/</a></p>
<p>document​.active​Element</p>
<p> 返回当前页面中获得焦点的元素,也就是说,如果此时用户按下了键盘上某个键,会在该元素上触发键盘事件.该属性是只读的.</p>
<h4 id="性能"><a href="#性能" class="headerlink" title="性能"></a>性能</h4><ol>
<li>尽量使用 flexbox 而不是老的布局模型。它运行速度更快，可为你的应用程序创造巨大的性能优势。</li>
<li>根据 Google Developer，渲染线程分为 主线程 (main thread) 和 合成线程 (compositor thread)。如果 CSS 动画只是改变 transforms 和 opacity，这时整个 CSS 动画得以在 合成线程完成（而JS动画则会在 主线程 执行，然后触发合成线程进行下一步操作），在 JS 执行一些昂贵的任务时，主线程繁忙，CSS 动画由于使用了合成线程可以保持流畅</li>
<li>CSS动画有天然事件支持（TransitionEnd、AnimationEnd，但是它们都需要针对浏览器加前缀），JS则需要自己写事件。</li>
<li>在实现一些小的交互动效的时候，就多考虑考虑 CSS 动画。对于一些复杂控制的动画，使用 javascript 比较可靠。</li>
</ol>
<h4 id="块元素是一个元素，占用了全部宽度，在前后都是换行符。"><a href="#块元素是一个元素，占用了全部宽度，在前后都是换行符。" class="headerlink" title="块元素是一个元素，占用了全部宽度，在前后都是换行符。"></a>块元素是一个元素，占用了全部宽度，在前后都是换行符。</h4>   <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">块元素的例子：</span><br><span class="line"></span><br><span class="line">&lt;h1&gt;</span><br><span class="line">&lt;p&gt;</span><br><span class="line">&lt;div&gt;</span><br><span class="line">内联元素只需要必要的宽度，不强制换行。</span><br><span class="line"></span><br><span class="line">内联元素的例子：</span><br><span class="line"></span><br><span class="line">&lt;span&gt;</span><br><span class="line">&lt;a&gt;</span><br></pre></td></tr></table></figure>
<h4 id="内容对齐（justify-content）属性应用在弹性容器上，把弹性项沿着弹性容器的主轴线（main-axis）对齐。"><a href="#内容对齐（justify-content）属性应用在弹性容器上，把弹性项沿着弹性容器的主轴线（main-axis）对齐。" class="headerlink" title="内容对齐（justify-content）属性应用在弹性容器上，把弹性项沿着弹性容器的主轴线（main axis）对齐。"></a>内容对齐（justify-content）属性应用在弹性容器上，把弹性项沿着弹性容器的主轴线（main axis）对齐。</h4><p>   align-items 设置或检索弹性盒子元素在侧轴（纵轴）方向上的对齐方式。<br>   设置”margin”值为”auto”值，自动获取弹性容器中剩余的空间。所以设置垂直方向margin值为”auto”，可以使弹性子元素在弹性容器的两上轴方向都完全居中。 当容器为flex时会自动居中。</p>
<p>   如果在元素上设置了 box-sizing: border-box; 则 padding(内边距) 和 border(边框) 也包含在 width 和 height 中:</p>
<p>   transform: rotateX(120deg);  x轴旋转 </p>
<h4 id="不被选中"><a href="#不被选中" class="headerlink" title="不被选中"></a>不被选中</h4><p>body{</p>
<p>-webkit-touch-callout: none;</p>
<p>-webkit-user-select: none;</p>
<p>-khtml-user-select: none;</p>
<p>-moz-user-select: none;</p>
<p>-ms-user-select: none;</p>
<p>user-select: none;</p>
<p>}</p>
<h4 id="隐藏"><a href="#隐藏" class="headerlink" title="隐藏"></a>隐藏</h4><p>1.opacity：0,该元素隐藏起来了，但不会改变页面布局，并且，如果该元素已经绑定了一些事件，如click事件也能触发 2.visibility:hidden,该元素隐藏起来了，但不会改变页面布局，但是不会触发该元素已经绑定的事件 3.display:node, 把元素隐藏起来，并且会改变页面布局，可以理解成在页面中把该元素删掉</p>
<h4 id="html-生成"><a href="#html-生成" class="headerlink" title="html 生成"></a>html 生成</h4><p>将html代码按照深度优先遍历来生成DOM树。 css文件下载完后也会进行渲染，生成相应的CSSOM。 当所有的css文件下载完且所有的CSSOM构建结束后，就会和DOM一起生成Render Tree。 接下来，浏览器就会进入Layout环节，将所有的节点位置计算出来。 最后，通过Painting环节将所有的节点内容呈现到屏幕上。</p>
<h4 id="base64"><a href="#base64" class="headerlink" title="base64"></a>base64</h4><p> TMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI 。可以使用 type 参数其类型，默认为 PNG 格式。图片的分辨率为96dpi。</p>
<h4 id="base64-渲染图片"><a href="#base64-渲染图片" class="headerlink" title="base64 渲染图片"></a>base64 渲染图片</h4><p>使用 Base64 编码渲染图片有以下优点：</p>
<p>有效减少 HTTP 请求次数<br>可对数据进行简单加密，无法肉眼获取信息<br>没有跨域问题，无需考虑图片缓存<br>凡事皆有利弊，使用 Base64 编码同时也会带来一些问题：</p>
<p>编码后文件体积增大，仅适用于小体积图片编码<br>增加了编码和解码的工作量<br>不支持 IE 8.0 以下版本   </p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/05/07/css/" data-id="ck3ya0yhn00050d8syraidhy6" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/css/">css</a></li></ul>

    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><a class="extend next" rel="next" href="/page/2/">__('next') &raquo;</a>
  </nav>
</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/css/">css</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/docker/">docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/es/">es</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/eslint/">eslint</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/hexo/">hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/http/">http</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/https/">https</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/interview/">interview</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/loadtest/">loadtest</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ops/">ops</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/pattern/">pattern</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/pm2/">pm2</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/postgre/">postgre</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/regex/">regex</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ts/">ts</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/useful-package/">useful package</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vue-eventloop-js/">vue eventloop js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/web-安全/">web 安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/webpack/">webpack</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/安全/">安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/零碎/">零碎</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/css/" style="font-size: 10px;">css</a> <a href="/tags/docker/" style="font-size: 10px;">docker</a> <a href="/tags/es/" style="font-size: 20px;">es</a> <a href="/tags/eslint/" style="font-size: 10px;">eslint</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/tags/http/" style="font-size: 10px;">http</a> <a href="/tags/https/" style="font-size: 10px;">https</a> <a href="/tags/interview/" style="font-size: 10px;">interview</a> <a href="/tags/loadtest/" style="font-size: 10px;">loadtest</a> <a href="/tags/ops/" style="font-size: 10px;">ops</a> <a href="/tags/pattern/" style="font-size: 10px;">pattern</a> <a href="/tags/pm2/" style="font-size: 10px;">pm2</a> <a href="/tags/postgre/" style="font-size: 10px;">postgre</a> <a href="/tags/regex/" style="font-size: 10px;">regex</a> <a href="/tags/ts/" style="font-size: 10px;">ts</a> <a href="/tags/useful-package/" style="font-size: 10px;">useful package</a> <a href="/tags/vue-eventloop-js/" style="font-size: 10px;">vue eventloop js</a> <a href="/tags/web-安全/" style="font-size: 10px;">web 安全</a> <a href="/tags/webpack/" style="font-size: 10px;">webpack</a> <a href="/tags/安全/" style="font-size: 10px;">安全</a> <a href="/tags/零碎/" style="font-size: 10px;">零碎</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/12/">December 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/05/">May 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/02/">February 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/02/">February 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/01/">January 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/12/">December 2016</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2019/12/09/security-1/">security</a>
          </li>
        
          <li>
            <a href="/2019/11/08/encoding/">encoding</a>
          </li>
        
          <li>
            <a href="/2019/08/23/graphql/">graphql</a>
          </li>
        
          <li>
            <a href="/2019/07/02/linux/">linux</a>
          </li>
        
          <li>
            <a href="/2019/07/02/es8/">es8</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2019 ryansecreat<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>

  </div>
</body>
</html>